package com.bf.electroplating.controller;

import com.bf.electroplating.pojo.dto.MessageByMnDTO;
import com.bf.electroplating.pojo.vo.equipment.ClientVo;
import com.bf.electroplating.pojo.vo.equipment.ConnectedClientVo;
import com.bf.electroplating.service.compoent.HJ212Server;
import com.bf.electroplating.pojo.vo.ResultVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.*;

/**
 * HJ212客户端管理控制器
 * 提供基于MN值的客户端管理功能
 */
@Slf4j
@RestController
@RequestMapping("/api/hj212/management")
@Tag ( name = "HJ212服务", description = "HJ212服务")
public class HJ212ManagementController {
    
    @Autowired
    private HJ212Server hj212Server;

    @PostMapping("/sendMessageByMn")
    @Operation ( summary = "根据mn码发送指令消息", description = "根据mn码发送指令消息")
    public ResultVO<Boolean> sendMessageByMn( @RequestBody @Validated MessageByMnDTO dto ) {
        try {
            log.info("接收到发送消息请求 - MN: {}, 内容: {}", dto.getMn (), dto.getMessage ());

            String message = dto.getMessage () + "\\r\\n";
            boolean success = hj212Server.sendMessageByMn( dto.getMn (), message );
            if (success) {
                return ResultVO.ok(true, "消息发送成功");
            } else {
                return ResultVO.fail("消息发送失败，客户端可能未连接");
            }
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return ResultVO.fail("发送消息失败");
        }
    }
    
    /**
     * 获取所有已连接的MN值列表
     */
    @GetMapping("/mns")
    public ResultVO< ConnectedClientVo  > getConnectedMns() {
        ConnectedClientVo clientVo = new ConnectedClientVo();
        List < ClientVo > clientVoList = new ArrayList <> ();
        try {
            // todo 这里是已连接的，将来需要从数据库查询
            Set<String> mns = hj212Server.getConnectedMns();
			for ( String mn : mns ) {
				ClientVo vo = new ClientVo ();
				String clientId = hj212Server.getClientIdByMn ( mn );
				String clientInfo = hj212Server.getMnToClientInfo ().get ( mn );
				SocketChannel channel = hj212Server.getClientByMn ( mn );
				String clientStatus = hj212Server.isClientConnected ( clientId ) ? "已连接" : "未连接";
				vo.setIsConnect ( clientStatus );
				vo.setMn ( mn );
				vo.setType ( clientInfo );
				vo.setClientId ( clientId );
				vo.setAddress ( channel.getRemoteAddress ().toString () );
                clientVoList.add ( vo );
			}
			clientVo.setClientVo ( clientVoList );
            clientVo.setCount ( mns.size () );
            return ResultVO.ok(clientVo);
        } catch (Exception e) {
            log.error("获取已连接MN值列表失败", e);
            return ResultVO.fail("获取已连接MN值列表失败");
        }
    }
    
    /**
     * 获取MN值到客户端信息的映射
     */
    @GetMapping("/clients")
    public ResultVO<Map<String, String>> getMnToClientInfo() {
        try {
            Map<String, String> clientInfo = hj212Server.getMnToClientInfo();
            return ResultVO.ok(clientInfo);
        } catch (Exception e) {
            log.error("获取客户端信息失败", e);
            return ResultVO.fail("获取客户端信息失败");
        }
    }
    
    /**
     * 检查指定MN值的客户端是否已连接
     */
    @GetMapping("/check/{mn}")
    public ResultVO<Boolean> isClientConnected(@PathVariable String mn) {
        try {
            boolean connected = hj212Server.isClientConnectedByMn(mn);
            return ResultVO.ok(connected);
        } catch (Exception e) {
            log.error("检查客户端连接状态失败", e);
            return ResultVO.fail("检查客户端连接状态失败");
        }
    }
    
    /**
     * 向指定MN值的客户端发送消息
     */
    @PostMapping("/send/{mn}")
    public ResultVO<Boolean> sendMessageToMn(@PathVariable String mn, @RequestBody Map<String, String> request) {
        try {
            String message = request.get("message");
            if (message == null || message.trim().isEmpty()) {
                return ResultVO.fail("消息内容不能为空");
            }
            
            boolean success = hj212Server.sendMessageByMn(mn, message);
            if (success) {
                return ResultVO.ok(true, "消息发送成功");
            } else {
                return ResultVO.fail("消息发送失败，客户端可能未连接");
            }
        } catch (Exception e) {
            log.error("发送消息失败", e);
            return ResultVO.fail("发送消息失败");
        }
    }


    
    /**
     * 断开指定MN值的客户端连接
     */
    @DeleteMapping("/disconnect/{mn}")
    public ResultVO<Boolean> disconnectClient(@PathVariable String mn) {
        try {
            boolean success = hj212Server.disconnectClientByMn(mn);
            if (success) {
                return ResultVO.ok(true, "客户端断开成功");
            } else {
                return ResultVO.fail("客户端断开失败，客户端可能未连接");
            }
        } catch (Exception e) {
            log.error("断开客户端连接失败", e);
            return ResultVO.fail("断开客户端连接失败");
        }
    }
    
    /**
     * 获取服务器状态信息
     */
    @GetMapping("/status")
    public ResultVO<Map<String, Object>> getServerStatus() {
        try {
            Map<String, Object> status = new HashMap<>();
            status.put("running", hj212Server.isRunning());
            status.put("connectedClientsCount", hj212Server.getConnectedClientsCount());
            status.put("connectedMns", hj212Server.getConnectedMns());
            status.put("mnToClientInfo", hj212Server.getMnToClientInfo());
            
            return ResultVO.ok(status);
        } catch (Exception e) {
            log.error("获取服务器状态失败", e);
            return ResultVO.fail("获取服务器状态失败");
        }
    }
    
    /**
     * 向所有客户端广播消息
     */
    @PostMapping("/broadcast")
    public ResultVO<Integer> broadcastMessage(@RequestBody Map<String, String> request) {
        try {
            String message = request.get("message");
            if (message == null || message.trim().isEmpty()) {
                return ResultVO.fail("消息内容不能为空");
            }
            
            int successCount = hj212Server.broadcastMessage(message);
            return ResultVO.ok(successCount, "广播消息完成，成功发送给 " + successCount + " 个客户端");
        } catch (Exception e) {
            log.error("广播消息失败", e);
            return ResultVO.fail("广播消息失败");
        }
    }
    
    /**
     * 启动对指定MN值机器的定时请求（每分钟一次）
     */
    @PostMapping("/schedule/start/{mn}")
    public ResultVO<Boolean> startScheduledRequest(@PathVariable String mn, @RequestBody Map<String, String> request) {
        try {
            String requestContent = request.get("requestContent");
            if (requestContent == null || requestContent.trim().isEmpty()) {
                return ResultVO.fail("请求内容不能为空");
            }
            
            boolean success = hj212Server.startScheduledRequest(mn, requestContent);
            if (success) {
                return ResultVO.ok(true, "定时请求启动成功，每分钟发送一次");
            } else {
                return ResultVO.fail("定时请求启动失败，请检查客户端是否已连接或是否已有定时任务在运行");
            }
        } catch (Exception e) {
            log.error("启动定时请求失败", e);
            return ResultVO.fail("启动定时请求失败");
        }
    }
    
    /**
     * 停止对指定MN值机器的定时请求
     */
    @PostMapping("/schedule/stop/{mn}")
    public ResultVO<Boolean> stopScheduledRequest(@PathVariable String mn) {
        try {
            boolean success = hj212Server.stopScheduledRequest(mn);
            if (success) {
                return ResultVO.ok(true, "定时请求停止成功");
            } else {
                return ResultVO.fail("定时请求停止失败，可能没有正在运行的定时任务");
            }
        } catch (Exception e) {
            log.error("停止定时请求失败", e);
            return ResultVO.fail("停止定时请求失败");
        }
    }
    
    /**
     * 检查指定MN值是否有定时任务在运行
     */
    @GetMapping("/schedule/check/{mn}")
    public ResultVO<Boolean> checkScheduledRequest(@PathVariable String mn) {
        try {
            boolean hasTask = hj212Server.hasScheduledRequest(mn);
            return ResultVO.ok(hasTask);
        } catch (Exception e) {
            log.error("检查定时任务状态失败", e);
            return ResultVO.fail("检查定时任务状态失败");
        }
    }
    
    /**
     * 获取所有正在运行的定时任务MN值列表
     */
    @GetMapping("/schedule/list")
    public ResultVO<Set<String>> getScheduledMns() {
        try {
            Set<String> scheduledMns = hj212Server.getScheduledMns();
            return ResultVO.ok(scheduledMns);
        } catch (Exception e) {
            log.error("获取定时任务列表失败", e);
            return ResultVO.fail("获取定时任务列表失败");
        }
    }
    
    /**
     * 停止所有定时任务
     */
    @PostMapping("/schedule/stop-all")
    public ResultVO<String> stopAllScheduledRequests() {
        try {
            hj212Server.stopAllScheduledRequests();
            return ResultVO.ok("所有定时任务已停止");
        } catch (Exception e) {
            log.error("停止所有定时任务失败", e);
            return ResultVO.fail("停止所有定时任务失败");
        }
    }
} 